package com.jy.app.lib.net;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.fastjson.TypeReference;
import com.jy.app.lib.R;
import com.jy.app.lib.application.BaseApplication;
import com.jy.app.lib.base.Constants;
import com.jy.app.lib.bean.BaseEntity;
import com.jy.app.lib.bean.BaseResponse;
import com.jy.app.lib.cache.HttpCache;
import com.jy.app.lib.utils.JsonUtil;
import com.jy.app.lib.utils.LogUtil;
import com.jy.app.lib.view.custom.LoadingDialog;
import com.jy.app.lib.view.uilistview.Pagin;
import com.loopj.android.http.BaseJsonHttpResponseHandler;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;

import cz.msebera.android.httpclient.Header;


/**
 * 解析json的httpResponseHandler
 * Created by jan on 2016/4/20.
 */
public class JsonHttpHandler<T> extends BaseJsonHttpResponseHandler<BaseResponse<T>> implements BaseResponseHandler<T> {

    private Context context;
    private String msgStr;
    private TypeReference<T> type = null;
    private BaseResponse<T> baseResponse;
    private LoadingDialog dialog;
    private Message message = new Message();
    private Handler handler = null;
    private Pagin pagin = null;
    private String url;
    private Double time;


    public void setDialogMsg(Context context, String msg){
        if(context!=null){
            dialog = new LoadingDialog(context,msg);
        }
    }

    public void setUrlandTime(String url,Double time){
        this.url = url;
        this.time = time;
    }

    public JsonHttpHandler(TypeReference type) {
        this(null,type,"",null,null);
    }

    public JsonHttpHandler(Context context,TypeReference type, String msg,Handler handler,Pagin pagin) {
        if(context!=null){
            dialog = new LoadingDialog(context,msg);
        }
        this.handler = handler;
        this.type = type;
        this.pagin = pagin;
    }

    public JsonHttpHandler(Context context,TypeReference type,String msg) {
       this(context,type,msg,null,null);
    }

    public JsonHttpHandler(Context context,TypeReference type) {
        this(context,type,"正在请求...",null,null);
    }

    public JsonHttpHandler(TypeReference type,Handler handler) {
        this(null,type,"正在请求...",handler,null);
    }

    public JsonHttpHandler(TypeReference type,Pagin pagin) {
        this(null,type,"",null,pagin);
    }


    @Override
    public void onStart() {
        if(dialog!=null){
            dialog.httpShow();
        }
        super.onStart();
    }

    @Override
    public void onFinish() {
        if(dialog!=null&&dialog.isShowing()){
            dialog.dismiss();
        }
        super.onFinish();
    }

    @Override
    public void onSuccess(int i, Header[] headers, String s, BaseResponse<T> type) {
        if (HttpUtil.ENABLE_LOG) {
            LogUtil.d("[HttpUtils]->response:" + s);
        }
        if (type != null) if (type instanceof BaseResponse) {
            baseResponse = ((BaseResponse) type);
            if (baseResponse.getCode()!=200){
                onFailure(baseResponse.getCode(),baseResponse.getMsg());
                return;
            }
            if (baseResponse.getData() != null && !"".equals(baseResponse.getData().toString().trim())) {
                Type type_ = ((ParameterizedType) this.type.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
                if (type_.equals(String.class)) {
                    onSuccess(baseResponse.getData(), baseResponse.getMsg());
                } else if (type_.equals(Boolean.class)) {
                    onSuccess((T) Boolean.valueOf((Boolean) baseResponse.getData()), baseResponse.getMsg());
                } else if (type_.equals(Integer.class)) {
                    onSuccess((T) Integer.valueOf((Integer) baseResponse.getData()), baseResponse.getMsg());
                } else if (type_.equals(Double.class)) {
                    onSuccess((T) Double.valueOf((Double) baseResponse.getData()), baseResponse.getMsg());
                } else {
                    try {
                        String jsonStr = baseResponse.getData().toString();
                        T obj = JsonUtil.parseObject(baseResponse.getData().toString(), this.type);
                        Class parentCls = obj.getClass().getSuperclass();
                        if(parentCls.equals(BaseEntity.class)){
                            ((BaseEntity)obj).androidJsonObject = jsonStr;
                        }else if(parentCls.equals(AbstractList.class)){
                            ArrayList list = (ArrayList)obj;
                            if(list.size()>0){
                                Class itemParentCls = list.get(0).getClass().getSuperclass();
                                if(itemParentCls.equals(BaseEntity.class)){
                                   for(Object entity:list){
                                       ((BaseEntity)entity).androidJsonObject = JsonUtil.toJson(entity);
                                   }
                                }
                            }
                        }
                        onSuccess(obj, baseResponse.getMsg());
                    } catch (Exception e) {
                        e.printStackTrace();
                        onFailure(10000, "数据解析异常");
                    }
                }
            } else {
                onSuccess(null, baseResponse.getMsg());
            }
            if (!TextUtils.isEmpty(url)&&time>0){
                HttpCache.getInstance().setUrlDataTime1(url,s,time);
            }
        }
        else {
            onFailure(10000, "数据处理异常");
        }
    }

    @Override
    public void onFailure(int statusCode, Header[] headers, Throwable throwable, String rawJsonData, BaseResponse<T> errorResponse) {
        LogUtil.d("HttpUtils onFailure->statusCode=" + statusCode+"  "+(throwable!=null?throwable.toString():""));
        if (rawJsonData !=null && statusCode == 1000){
            onFailure(10000,rawJsonData);
        }else{
            String error = throwable!=null?throwable.toString():"";
            if (error == null) error = "";
            String[] str =  error.split(":");
            onFailure(statusCode,BaseApplication.appContext.getString(R.string.your_network_not_ok)+(str.length>0?"\n"+str[str.length-1]+"\n":""));
        }

    }

    @Override
    protected BaseResponse<T> parseResponse(String s, boolean isFail) {
        BaseResponse<T> t = null;
        try {
            if (!isFail) {
                t = (BaseResponse<T>) JsonUtil.parseObject(s, new TypeReference<BaseResponse<T>>() {
                });
            } else {
                //TODO 错误类型我们要定义好参数和实体，在此序列
            }
        } catch (Exception e) {
            Log.e("JsonResponseHttpHandler", "parseResponse err:", e);
            onFailure(10000, "数据处理异常");
        }
        return t;
    }

    @Override
    public void onSuccess(T t, String msg) {
        onSuccess(t);
    }

    @Override
    public void onSuccess(T response) {
        if(pagin!=null){
            if(response instanceof List){
                try {
                    pagin.setItemData((List) response);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return;
        }
        message.what = Constants.MSG_HTTP_SUCCESS;
        if(response instanceof List){
            message.obj = (List)response;
        }else {
            message.obj = response;
        }
        if(handler!=null)
            handler.sendMessage(message);
        onSuccess(message);
    }

    public void onSuccess(Message msg) {
    }

    public void onFailure(Message msg) {
    }

    @Override
    public void onFailure(int failCode, String failSource) {
        if (pagin != null) {
            pagin.setError();
            return;
        }
        message.what = Constants.MSG_HTTP_FAIL;
        message.obj = failSource;
        message.arg1 = failCode;
        if(handler!=null)
            handler.sendMessage(message);
        onFailure(message);
    }

    public BaseResponse<T> getOriginalResponse(){
        return baseResponse;
    }
}
